#!/usr/bin/env python
#coding=utf-8
from models import Mail
import getopt,sys,os,datetime,re
from ttorm.db.transaction import commit_manually,commit_on_success,autocommit,commit
from ttorm.core.validators import ValidationError
from ttorm.utils.encoding import smart_str

class Manager(object):
    mail_re = re.compile(r"(@163.com$)|(@126.com$)|(@21cn.com$)|(\.cn$)|(^info@)|(\.jpg$)|(\.\d+$)|(\d+\.\d+$)", re.I)
    
    def __call__(self, argv):
        opts, argv = getopt.getopt(argv, "l:u:ep:f:s:doi:", ['load=', 'update=', 'state=', 'export'])
        dopts = dict(opts)
        for opt, arg in opts:
            if opt in ['-l', '--load']:
                defaultstate = int(dopts.get('-s', 0))
                self.load(arg, defaultstate)
            if opt in ['-u', '--update']:
                self.update(arg)
            if opt in ['-e', '--export']:
                filename = dopts.get('-f', None)
                arg = dopts.get('-p', None)
                delete = dopts.has_key('-d')
                sort = not dopts.has_key('-o')
                limit = dopts.get('-i', -1)
                self.export(params = arg, delete=delete, sort=sort, filename=filename, limit=limit)
    
    def check_file(self, filename):
        if not os.path.exists(filename):
            print filename, 'does not exists'
            return False
        return True
    
    def check_email(self, mail_str):
        return self.mail_re.search(mail_str)
    
    def load(self, filename, defaultstate=0):
        if self.check_file(filename):
            f = file(filename).read().split('\n')
            self._load(f, defaultstate)
    
        
    @commit_manually
    def _load(self, mail_list, defaultstate=0):
        c=0
        for i in mail_list:
            i = i.lower()
            if self.check_email(i):
                print i, 'not valid'
                continue
            try:
                m,n = Mail.objects.get_or_create(name=i, validate=True)
            except ValidationError, e:
                print i,e
            except Exception,e:
                print i,e
            else:
                if n:
                    c+=1
                    if defaultstate != 0:
                        m.state=defaultstate
                        m.save()
                    if c%1000 == 0:
                        print c
                        
        commit()
        print 'add',c,'new mail'
    
    def update(self, filename):
        if self.check_file(filename):
            f = file(filename).read().split('\n')
            mail_list = []
            for i in f:
                j = i.split('\t')
                if self.check_email(j[0]):
                    print i, 'not valid'
                    continue
                item=[j[0], len(j) == 1 and 0 or int(j[1])]
                mail_list.append(item)
            self._update(mail_list)
            
    @commit_manually
    def _update(self, mail_list):
        c=0
        u=0
        for i in mail_list:
            try:
                m,n = Mail.objects.get_or_create(name=i[0].lower(), validate=True)
            except ValidationError, e:
                print e
            else:
                if n:
                    c+=1
                else:
                    u+=1
                m.state = i[1]
                m.save()
        commit()
        print 'add',c,'new mail, update',u,'mail'

    def export(self, params=None, filename=None, delete=False, sort=True, limit=-1):
        if params is None:
            lookup_params = {}
        else:
            lookup_params = dict([x.split('=') for x in params.split(';')])
            for key, value in lookup_params.items():
                if not isinstance(key, str):
                    del lookup_params[key]
                    lookup_params[smart_str(key)] = value
                
        if delete:
            lookup_params['state__lt'] = 0
        else:
            lookup_params['state__gte'] = 0
        qs = Mail.objects.filter(**lookup_params)
        if limit != -1:
            qs = qs[:limit]
        mail_list = [x.name for x in qs]
        if sort:
            mail_list.sort()
        mail_list = '\n'.join(mail_list)
        if filename is None:
            print mail_list
        else:
            a = file(filename,'w')
            a.write(mail_list)
            a.close()

if __name__ == '__main__':
    m = Manager()
    m(sys.argv[1:])
        
    